//============[功能]:实现各个角色的功能=============
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

#include "tlinklist.h"
#include "slinklist.h"
#include "filedata.h"
#include "function.h"
#include "screen.h"

/*
//定义校长数据结构,便于和老师,学生一起分析
typedef struct 
{
	char password[20];
}*pLink;
*/

//按任意键返回->有待于改进
bool Return_Key()
{
	printf("\n请按任意键返回:");
	char arb = 0;
	scanf("%hhd",&arb);
	return true;
}
//3秒后自动返回
bool Return_Time()
{
	printf("\n3秒后将会自动返回......");
	//sleep(3);
	printf("\n");//[问题]:若系统延时与打印句在同一行,就会[先延时再打印]
				 //[解决办法]:将延时语句和打印句用[换行符隔开]
	sleep(3);
	return true;
}
//密码输入,校验
bool Check_Password(char r_password[20])
{
	printf("\n请输入密码(共有3次输入机会):");
	char num = 3;//输入次数
	char i_password[20];//输入密码

	while(num != 0)
	{
		num--;

		scanf("%s",i_password);
		
		if(strcmp(i_password,r_password) == 0) 
		{
			printf("密码输入正确!\n");
			Return_Time();
			return true;
		}
		printf("\n密码输入错误,请重新输入(还剩%hhd次机会):",num);
	}
	printf("\n===请确认密码再登录===\n");
	Return_Time();
	return false;
}

//==========[开发人员:developer]==========

//密码校验
bool Check_Password_D()
{
	char password[20] = "5501790";//开发人员的密码
	return Check_Password(password);
}
//修改校长密码->不显示屏幕
bool Modify_Password_P(pLink PL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [开发人员-重置校长密码] <------\n\n");

	//修改
	printf("\n请输入新的密码(12位以内的字符):");
	scanf("%s",PL->password);
	printf("\n密码修改成功!\n");

	//返回
	Return_Time();
	return true;
}
// WMS 系统初始化:将教师和学生的数据链表清零，并重置校长密码
bool Init_System(pLink PL,tLink TL,sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [开发人员-系统初始化] <------\n\n");

	printf("\n请输入校长(超级管理员)密码:");
	scanf("%s",PL->password);

	Init_tLink(TL);//[问题]:出现内存泄露问题,猜测是由于数据结构更改造成
	Init_sLink(SL);//[解决办法]:没问题,受处理学生成绩总评的影响
	printf("\n系统初始化成功!\n");
	
	//返回
	Return_Time();
	return true;
}

//==========[校长:principal]==========

//密码校验
bool Check_Password_P(pLink PL)
{
	return Check_Password(PL->password);
}
//单个输入教师信息：单个导入
bool Simple_Input_TD(tLink TL)
{	
	//界面显示
	Head_Screen();
	printf("\n------> [校长-单个导入教师信息] <------\n\n");
	
	printf("\n工号 (12位字符)密码 姓名 电话号码 任职状态(0:在职,1:离职)\n");
	printf("\n请按照上述格式导入教师信息:");
	tNode* tmp = (tNode*)malloc(sizeof(tNode));
	scanf("%d%s%s%s%hhd",&tmp->id,tmp->password,tmp->name,tmp->phone,&tmp->state);
	//printf("键入成功\n");
	Insert_tLink(TL,tmp->id,tmp->password,tmp->name,tmp->phone,tmp->state);
	free(tmp);
	printf("\n导入成功!\n");

	//返回
	Return_Time();
	return true;
}
//查看,修改某个教师信息(修改教师状态，重置教师密码)
bool Check_Modify_TD(tLink TL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [校长-查看/修改教师信息] <------\n\n");

	//输入工号
	printf("\n请输入查询教师的工号:");
	int id = -1;
	tNode* node = NULL;
	
	//确认该工号存在
	while(1)
	{
		scanf("%d",&id);
		node = Search_tLink(TL,id);
		if(node == NULL)
		{
			printf("\n不存在该工号,请重新确认输入:");
			continue;
		}
		break;
	}

	//查看
	printf("\n工号:%d 姓名:%s 电话号码:%s ",node->id,node->name,node->phone);
	printf("任职状态:");
	switch(node->state)
	{
		case 0 : printf("在职\n");break;
		case 1 : printf("离职\n");break;
		default : printf("未知状态\n");break;
	}
	//修改
	printf("\n0:工号 1:姓名 2:电话号码 3:任职状态 4:重置密码\n\n9:返回\n");
	printf("\n请选择修改项目,或按9返回上一界面:");
	char flag = -1;
	while(1)
	{
		scanf("%hhd",&flag);
	 	switch(flag)
		{
			case 0 : printf("\n请输入新的工号:");scanf("%d",&node->id);printf("工号修改成功!\n");break;
			case 1 : printf("\n请输入新的姓名:");scanf("%s",node->name);printf("姓名修改成功!\n");break;
			case 2 : printf("\n请输入新的电话:");scanf("%s",node->phone);printf("电话修改成功!\n");break;
			case 3 : printf("\n请输入新的状态(0:在职 1:离职):");scanf("%hhd",&node->state);printf("状态修改成功!\n");break;
			case 4 : printf("\n请输入新的密码:");scanf("%s",node->password);printf("密码修改成功!\n");break;
			case 9 : return true;//结束当前界面的操作,返回上一界面
			default : printf("\n选择无效,请重新输入:");continue;
		}
		break;
	}

	//返回
	Return_Time();
	return true;
}
//查看离职教师信息(展示id,name,phone)
bool Check_Quit_TD(tLink TL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [校长-查看离职教师信息] <------\n\n");
	
	tNode* node = TL->head;
	printf("\n离职教师信息如下:\n");
	while(node != NULL)
	{
		if(node->state == 1)
		{
			printf("\n%d %s %s\n",node->id,node->name,node->phone);
		}
		node = node->next;
	}

	//返回
	Return_Key();
	return true;
}
//重置自己密码->请按任意键结束->限定时间内返回
bool Reset_Password_P(pLink PL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [校长-重置密码] <------\n\n");
	
	printf("\n请输入你的新密码:");
	scanf("%s",PL->password);
	printf("\n密码重置成功!\n");
	
	//返回
	Return_Time();
	return true;
}

//==========[教师:teacher]==========

//密码校验:完成输入,检验,输出的功能......返回self_id
int Check_Password_T(tLink TL)
{
	//确认工号
	printf("\n请输入工号:");
	int self_id = -1;
	tNode* node = NULL;
	while(1)
	{
		scanf("%d",&self_id);
		node = Search_tLink(TL,self_id);
		if(node != NULL)
		{
			break;
		}
		printf("\n不存在该工号,请确认后重新输入:");
	}
	//确认密码
	if(Check_Password(node->password) == true) return node->id;
	else return -1;
}
//批量上传学生信息(添加)
bool Batch_Input_SD(sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-批量上传学生信息] <------\n\n");
	
	//无论数据导入是否成功,都会进入返回界面
	Add_Data_S(SL);

	//返回
	Return_Time();
	return true;
}
//批量上传学生分数(添加)
bool Batch_Input_SS(sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-批量上传学生分数] <------\n\n");
	
	//无论分数导入是否成功,都会进入返回界面
	Add_Data_Score(SL);

	//分数排位
	Sort_sLink(SL,SL->head,SL->tail,1);

	//返回
	Return_Time();
	return true;
}
//查看,修改某个学生信息(修改学生状态,修改学生分数,重置学生密码)
bool Check_Modify_SD(sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-查看/修改学生信息] <------\n\n");
	
	//输入学生学号
	printf("\n请输入查询学生的学号:");
	int id = -1;
	sNode* node = NULL;

	//确认存在该学号
	while(1)
	{
		scanf("%d",&id);
		node = Search_sLink(SL,id);
		if(node == NULL)
		{
			printf("\n不存在该学号,请重新确认输入:");
			continue;
		}
		break;
	}
	//查看
	printf("\n学号:%d 姓名:%s 性别:%s\n",node->id,node->name,node->sex);
	printf("\n身份证号:%s 电话号码:%s 就读状态:",node->idcard,node->phone);
	switch(node->state)
	{
		case 0 : printf("在读\n");break;
		case 1 : printf("退学\n");break;
		default : printf("未知状态\n");break;
	}
	printf("\n语文:%.2lf 数学:%.2lf 英语:%.2lf\n总分:%.2lf 排名:%d\n",node->ChineseScore,node->MathScore,node->EnglishScore,node->TotalScore,node->ScoreRank);
	//修改
	printf("\n0:学号 1:姓名 2:重置密码 3:身份证号 4:电话号码 5:就读状态 6:语文成绩 7:数学成绩 8:英语成绩\n\n9:返回\n");
	printf("\n请选择修改项目,或按9返回上一界面:");
	char flag = -1;
	bool sflag = false;
	while(1)
	{
		scanf("%hhd",&flag);
		switch(flag)
		{
			case 0 : printf("\n请输入新的工号:");scanf("%d",&node->id);printf("工号修改成功!\n");break;
			case 1 : printf("\n请输入新的姓名:");scanf("%s",node->name);printf("姓名修改成功!\n");break;
			case 2 : printf("\n请输入新的密码:");scanf("%s",node->password);printf("密码重置成功!\n");break;
			case 3 : printf("\n请输入新的身份证号:");scanf("%s",node->idcard);printf("身份证号修改成功!\n");break;
			case 4 : printf("\n请输入新的电话号码:");scanf("%s",node->phone);printf("电话号码修改成功!\n");break;
			case 5 : printf("\n请输入新的就读状态(0:在读 1:退学):");scanf("%hhd",&node->state);printf("就读状态修改成功!\n");break;
			case 6 : printf("\n请输入新的语文成绩:");scanf("%f",&node->ChineseScore);printf("语文成绩修改成功!\n");sflag = true;break;
			case 7 : printf("\n请输入新的数学成绩:");scanf("%f",&node->MathScore);printf("数学成绩修改成功!\n");sflag = true;break;
			case 8 : printf("\n请输入新的英语成绩:");scanf("%f",&node->EnglishScore);printf("英语成绩修改成功!\n");sflag = true;break;
			case 9 : return true;//结束当前界面的操作,返回上一界面
			default : printf("\n选择无效,请重新输入:");continue;
		}
		break;
	}
	
	if(sflag == true)//如果三科分数改变了
	{
		//对总分进行处理
		node->TotalScore = node->ChineseScore + node->MathScore + node->EnglishScore;
		//对排名进行重置
		Sort_sLink(SL,SL->head,SL->tail,1);
	}

	//返回
	Return_Time();
	return true;
}
//查看退学学生信息(展示id,name,sex,idcard,phone)
bool Check_Quit_SD(sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-查看退学学生信息] <------\n\n");
	
	sNode* node = SL->head;
	printf("\n退学学生信息如下:\n");
	while(node != NULL)
	{
		if(node->state == 1)
		{
			printf("\n%d %s %s %s %s\n",node->id,node->name,node->sex,node->idcard,node->phone);
		}
		node = node->next;
	}
	
	//返回
	Return_Key();
	return true;
}
//查看学生成绩总评
/*[问题]:结构体内存过度(存入的量大于申请的量)
*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x085b2330 ***
*** glibc detected *** ./a.out: malloc(): memory corruption: 0x085b2340 ***
[解决办法]:数据赋值时[未作类型转化],造成内存过度----->无效
*/
bool Check_SSC(sLink SL)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-查看学生成绩总评] <------\n\n");
	
	sResult SR = Result_sLink(SL);
	//sResult SR = (sResult)malloc(sizeof(sResult));
	//if(SR == NULL) return false;
	
	//Result_sLink(SL,SR);

	printf("\n学生成绩分析数据如下:\n");
	printf("\n单科最高分: %.2lf(语文) %.2lf(数学) %.2lf(英语)\n",SR->CHScore,SR->MHScore,SR->EHScore);
	printf("\n单科平均分: %.2lf(语文) %.2lf(数学) %.2lf(英语)\n",SR->CAScore,SR->MAScore,SR->EAScore);

	//free(SR);//函数结束后,变量自动清空
	//SR = NULL;

	//返回
	Return_Key();
	return true;
}
//重置自己密码
bool Reset_Password_T(tLink TL,int id)
{
	//界面显示
	Head_Screen();
	printf("\n------> [教师-重置密码] <------\n\n");
	
	tNode* node = Search_tLink(TL,id);

	printf("\n请输入你的新密码:");
	scanf("%s",node->password);
	
	printf("\n密码重置成功!\n");

	//返回
	Return_Time();
	return true;
}

//==========[学生:student]==========

//密码校验:完成输入,检验,输出的功能......返回self_id
int Check_Password_S(sLink SL)
{
	//确认学号
	printf("\n请输入学号:");
	int self_id = -1;
	sNode* node = NULL;
	while(1)
	{
		scanf("%d",&self_id);
		node = Search_sLink(SL,self_id);
		if(node != NULL)
		{
			break;
		}
		printf("\n不存在该学号,请确认后重新输入:");
	}
	//确认密码
	if(Check_Password(node->password) == true) return node->id;
	else return -1;
}
//查看自己的成绩
bool Check_Score_SP(sLink SL,int id)
{
	//界面显示
	Head_Screen();
	printf("\n------> [学生-查看成绩] <------\n\n");
	
	sNode* node = Search_sLink(SL,id);
	printf("\n你的成绩如下:\n");
	printf("\n语文:%.2lf 数学:%.2lf 英语:%.2lf\n",node->ChineseScore,node->MathScore,node->EnglishScore);
	printf("\n总分:%.2lf 排名:%d\n",node->TotalScore,node->ScoreRank);
	
	//返回
	Return_Key();
	return true;
}
//重置自己密码
bool Reset_Password_S(sLink SL,int id)
{
	//界面显示
	Head_Screen();
	printf("\n------> [学生-重置密码] <------\n\n");
	
	sNode* node = Search_sLink(SL,id);

	printf("\n请输入你的新密码:");
	scanf("%s",node->password);
	
	printf("\n密码重置成功!\n");

	//返回
	Return_Time();
	return true;
}

